#ifndef _VL_RTSP_BUFFER__H_
#define _VL_RTSP_BUFFER__H_

#include "defs.h"

namespace VLRTSP {

/**
 * @Author: CimZzz
 * @Date: 2022-01-07 14:19:36
 * 
 * 缺省初始化缓冲区长度
 */
#define BUFFER_DEFAULT_INIT_SIZE 255

/**
 * @Author: CimZzz
 * @Date: 2022-01-07 14:39:25
 * 
 * 最小字节增长尺寸
 */
#define BUFFER_MIN_INC_SIZE 64

/**
 * @Author: CimZzz
 * @Date: 2022-01-07 14:30:26
 * 
 * 字节缓冲区
 */
class Buffer {
public:
	/**
	 * @Author: CimZzz
	 * @Date: 2022-01-07 14:14:06
	 * 
	 * 构造函数，初始化缓冲长度
	 * @param initSize 初始化缓冲长度
	 */
	explicit Buffer(uint32_t initSize = BUFFER_DEFAULT_INIT_SIZE);

	/**
	 * @Author: CimZzz
	 * @Date: 2022-01-07 14:21:04
	 * 
	 * 析构函数
	 * 回收缓冲资源
	 */
	~Buffer();

	/**
	 * @Author: CimZzz
	 * @Date: 2022-01-07 17:02:46
	 * 
	 * 获取当前缓冲长度
	 * @return 缓冲长度
	 */
	uint32_t getBufferLength();

	/**
	 * @Author: CimZzz
	 * @Date: 2022-01-10 16:57:05
	 * 
	 * 获取当前缓冲区已申请的内存长度
	 * @return 已申请的内存长度
	 */
	uint32_t getTotalLength();

	/**
	 * @Author: CimZzz
	 * @Date: 2022-01-10 17:06:07
	 * 
	 * 重置当前内存缓冲区
	 */
	void reset();

	/**
	 * @Author: CimZzz
	 * @Date: 2022-01-07 14:29:07
	 * 
	 * 复制字节到当前缓冲区中
	 * @param buffer 字节数组指针
	 * @param offset 偏移位置
	 * @param length 复制长度
	 */
	void appendBuffer(const uint8_t* buffer, uint32_t offset, uint32_t length);

	/**
	 * @Author: CimZzz
	 * @Date: 2022-01-07 14:29:07
	 * 
	 * 复制字节到当前缓冲区中
	 * @param buffer 字节缓冲区
	 * @param offset 偏移位置
	 * @param length 复制长度，0 表示复制到末尾
	 */
	void appendBuffer(const Buffer* buffer, uint32_t offset = 0, uint32_t length = 0);

	/**
	 * @Author: CimZzz
	 * @Date: 2022-01-07 15:58:10
	 * 
	 * 复制单字节到当前缓冲区中
	 * @param byte 单字节
	 */
	void appendByte(uint8_t byte);

	/**
	 * @Author: CimZzz
	 * @Date: 2022-01-14 15:24:27
	 * 
	 * 在当前缓冲区中插入字节
	 * @param insertIndex 插入位置
	 * @param buffer 字节数组指针
	 * @param offset 偏移位置
	 * @param length 复制长度
	 * 
	 * @note 如果插入位置超过当前字节长度，那么缓存字节长度会变更到插入之后的字节尾部，中间间隔部分会填充 0
	 */
	void insertBuffer(uint32_t insertIndex, const uint8_t* buffer, uint32_t offset, uint32_t length);

	/**
	 * @Author: CimZzz
	 * @Date: 2022-01-14 15:25:13
	 * 
	 * 在当前缓冲区中插入字节
	 * @param insertIndex 插入位置
	 * @param buffer 字节缓冲区
	 * @param offset 偏移位置
	 * @param length 复制长度，0 表示复制到末尾
	 * 
	 * @note 如果插入位置超过当前字节长度，那么缓存字节长度会变更到插入之后的字节尾部，中间间隔部分会填充 0
	 */
	void insertBuffer(uint32_t insertIndex, const Buffer* buffer, uint32_t offset = 0, uint32_t length = 0);	
	
	/**
	 * @Author: CimZzz
	 * @Date: 2022-01-07 15:58:10
	 * 
	 * 在当前缓冲区中插入单字节
	 * @param insertIndex 插入位置
	 * @param byte 单字节
	 * 
	 * @note 如果插入位置超过当前字节长度，那么缓存字节长度会变更到插入之后的字节尾部，中间间隔部分会填充 0
	 */
	void appendByte(uint32_t insertIndex, uint8_t byte);

	/**
	 * @Author: CimZzz
	 * @Date: 2022-01-12 17:05:13
	 * 
	 * 将打印的字符串添加到当前缓冲区中
	 * @param fmt 格式化字符串
	 * @param ... 变长参数，用于填充格式化字符串参数
	 */
	void appendPrint(const char * fmt, ...);

	/**
	 * @Author: CimZzz
	 * @Date: 2022-01-11 18:54:06
	 * 
	 * 从字节缓冲区中移除字节
	 * @param offset 偏移位置
	 * @param length 移除长度
	 * 
	 * @note 当 offset == 0, length == 0 时，作用等同于 [reset]
	 */
	void removeRange(uint32_t offset = 0, uint32_t length = 0);

	/**
	 * @Author: CimZzz
	 * @Date: 2022-01-07 14:22:31
	 * 
	 * 克隆当前缓冲资源
	 * @param offset 偏移位置
	 * @param length 克隆长度，0 表示克隆到末尾
	 */
	uint8_t* getBufferClone(uint32_t offset = 0, uint32_t length = 0);

	/**
	 * @Author: CimZzz
	 * @Date: 2022-01-07 17:04:45
	 * 
	 * 直接获取当前缓存区指针
	 * @return 缓冲区指针
	 */
	uint8_t* getBuffer() const;

	/**
	 * @Author: CimZzz
	 * @Date: 2022-01-10 16:56:37
	 * 
	 * 确保当前缓冲区已申请内存长度
	 * @param size 已申请内存长度
	 */
	bool makeSureTotalLength(uint32_t size);
private:
	/**
	 * @Author: CimZzz
	 * @Date: 2022-01-07 14:15:15
	 * 
	 * 内部缓冲指针
	 */
	uint8_t* buffer;

	/**
	 * @Author: CimZzz
	 * @Date: 2022-01-07 14:23:49
	 * 
	 * 已缓冲长度
	 */
	uint32_t bufferLength;

	/**
	 * @Author: CimZzz
	 * @Date: 2022-01-07 14:24:10
	 * 
	 * 缓冲区长度
	 */
	uint32_t totalLength;

	/**
	 * @Author: CimZzz
	 * @Date: 2022-01-07 14:33:06
	 * 
	 * 添加指定字节到当前缓冲区指定位置中
	 * @param currentOffset 当前字节缓冲区指定位置
	 * @param buffer 字节数组指针
	 * @param offset 偏移位置
	 * @param length 转移长度
	 */
	void _appendBuffer(uint32_t currentOffset, const uint8_t* buffer, uint32_t offset, uint32_t length);
};


}


#endif //_VL_RTSP_BUFFER__H_
